/**Spring Bean生命周期
 * 0.扫描解析Bean的定义和注册元数据
 * 1.BeanDefinition:BeanFactoryPostProcessor(postProcessBeanFactory)
 * 2.实例化:InstantiationAwareBeanPostProcessor(postProcessBeforeInstantiation)
 * 3.属性注入:InstantiationAwareBeanPostProcessor(postProcessAfterInitialization->postProcessProperties)
 * 4.初始化:BeanPostProcessor(Aware接口方法-->@PostConstruct-->InitializingBean.afterPropertiesSet-->init-method-->postProcessAfterInitialization)
 * 5.销毁:@PreDestroy-->DiposibleBean.destory()-->destroy-method
 *另一个维度分类如下：
 *  1、Bean自身的方法：配置文件中<bean>的init-method和destroy-method指定的方法或注解中的@PostConstruct/@PreDestroy
 *   2、Bean级生命周期接口方法：BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
 *   3、容器级生命周期接口方法：InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现，一般称它们的实现类为“后处理器”。
 *  4、工厂后处理器接口方法：这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等
 *
 *创建Bean：BeanFactoryPostProcessor->BeanPostProcessor->InstantiationAwareBeanPostProcessor->BeanNameAware.setBeanName->BeanFactoryAware.setBeanFactory-->ApplicationContextAware.setApplcationContext
 *BeanPostProcessor.postProcessBeforeInitialization-->InitializingBean.afterPropertiesSet->init-method->BeanPostProcessor.postProcessAfterInitialization->InstantiationAwareBeanPostProcessor.postProcessAfterInitialization

 */
package com.example.demospringbootbean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
public class BeanLifecycleDemo {
    public static void showLifeCycle() {

        System.out.println("开始初始化Spring容器......");

        ApplicationContext factory = new ClassPathXmlApplicationContext("beans3.xml");

        System.out.println("Spring容器初始化成功!");

        //获取Preson对象，并使用
        Person person = factory.getBean("person",Person.class);
        System.out.println(person);

        System.out.println("现在开始关闭Spring容器......");
//        ((ClassPathXmlApplicationContext)factory).registerShutdownHook();
        ((ClassPathXmlApplicationContext) factory).close();
    }
    public static void showLifeCycleByAnnotation() {

        System.out.println("开始初始化Spring容器......");
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.example.demospringbootbean");


        System.out.println("Spring容器初始化成功!");

        //获取Preson对象，并使用

        ClassBB classBB= context.getBean("classBB",ClassBB.class);
        System.out.println(classBB);

        System.out.println("现在开始关闭Spring容器......");

//        if(context instanceof AbstractApplicationContext)
//        {
//            ((AbstractApplicationContext)context).registerShutdownHook();
//
//        }
        context.close();
    }

}
